package com.ecarx.camera.ui.settings;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import com.ecarx.camera.R;
import com.ecarx.camera.constant.Constants;
import com.ecarx.camera.ui.BaseDialog;
import com.ecarx.camera.ui.BaseFragment;
import com.ecarx.camera.ui.main.MainFragment;
import com.ecarx.camera.utils.DialogUtils;
import com.ecarx.camera.utils.LogUtils;
import com.ecarx.camera.utils.Utils;
import com.ecarx.camera.worker.camera.dvr.DvrManager;
import com.ecarx.camera.worker.camera.dvr.IDvrAPI;
import com.ecarx.camera.worker.car.aosp.AospCarManager;
import com.ecarx.camera.worker.config.ConfigManager;
import com.jeremyliao.liveeventbus.utils.AppUtils;

public class SettingsFragment extends BaseFragment {

    private static final String TAG = "SettingsFragment";

    public static final int MIN_PERCENTAGE = 0;
    public static final int MAX_PERCENTAGE = 100;
    private static final int FORMATTING_MAX_MILLIS = 30 * 1000;

    private TextView[] fgColorTvs;
    private View[] viewDivideLines;
    private RadioGroup mLoopRecordRg;

    private MainFragment mMainFragment;

    private TextView mTfCardBtn;
    private ProgressBar mTfCardProgressBar;
    private TextView mTfCardPercentageTxt;
    private TextView mTvTitlePrivacyPolicy;
    View tvTitlePrivacyPolicy;
    private Dialog mTfCardFormatDialog, mTfCardFormatLoadingDialog;
    private boolean isRequiresDistractionOptimization = false;

    //延迟更新循环录制RadioGroup的消息
    private static final int HANDLER_DELAY_UPDATE_RECORD_RADIO_GROUP = 1;

    //是否需要延迟更新循环录制RadioGroup
    private boolean isNeedDelayUpdateLoopRecordRadioGroup = false;

    private Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(android.os.Message msg) {
            if (msg.what == HANDLER_DELAY_UPDATE_RECORD_RADIO_GROUP) {
                updateLoopRecordRadioGroup();
            }
        }
    };

    private final Runnable mDismissForFormatTimeoutRunnable = () -> {
        LogUtils.d(TAG, "formatting timeout!");
        dismissTfCardFormatLoadingDialog();
    };
    private View.OnClickListener mFormatCancelClickListener = v -> {
        dismissTfCardFormatDialog();
    };
    private View.OnClickListener mFormatConfirmClickListener = v -> {
        dismissTfCardFormatDialog();
        // 开始TfCard格式化
        boolean startSuccess = DvrManager.get().doDvrSdcardFormat();
        if (startSuccess) {
            showTfCardFormatLoadingDialog();
        }
    };

    private final BaseDialog.OnDismissListener mPrivacyDismissListener = dialog -> {
        LogUtils.d(TAG, "onPrivacy Dialog dismiss");
        if (mMainFragment != null) {
            mMainFragment.showPrivacySettingsShade(false);
        }
    };

    private final IDvrAPI.IDvrConfigWatcher mDvrConfigWatcher = new IDvrAPI.IDvrConfigWatcher() {
        @Override
        public void onDvrGeneralRecordResolutionChanged(int resolution) {
            LogUtils.d(TAG, "onDvrGeneralRecordResolutionChanged, resolution:" + resolution);
        }

        @Override
        public void onDvrGeneralRecordDurationChanged(int duration) {
            LogUtils.d(TAG, "onDvrGeneralRecordDurationChanged, duration:" + duration + " isNeedDelayUpdate:" + isNeedDelayUpdateLoopRecordRadioGroup);
            if (isNeedDelayUpdateLoopRecordRadioGroup) {
                sendDelayUpdateLoopRecordRadioGroupMsg();
            } else {
                updateLoopRecordRadioGroup();
            }
        }

        @Override
        public void onDvrGeneraRecordMicMuteChanged(boolean mute) {
            LogUtils.d(TAG, "onDvrGeneraRecordMicMuteChanged, mute:" + mute);
        }

        @Override
        public void onDvrSdcardUsedPercentageChanged(int percentage) {
            LogUtils.d(TAG, "onDvrSdcardUsedPercentageChanged, percentage:" + percentage);
            updateTfCardLay();
        }
    };

    private final IDvrAPI.ISdcardStateWatcher mSdcardStateWatcher = new IDvrAPI.ISdcardStateWatcher() {
        @Override
        public void onSdcardStateUnknown() {
            LogUtils.d(TAG, "onSdcardStateUnknown");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateNormal() {
            LogUtils.d(TAG, "onSdcardStateNormal");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateNoSdcard() {
            LogUtils.d(TAG, "onSdcardStateNoSdcard");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateError() {
            LogUtils.d(TAG, "onSdcardStateError");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateInitializeFail() {
            LogUtils.d(TAG, "onSdcardStateInitializeFail");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStatePoorWritePerformance() {
            LogUtils.d(TAG, "onSdcardStatePoorWritePerformance");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateNotFormatted() {
            LogUtils.d(TAG, "onSdcardStateNotFormatted");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateFormatting() {
            LogUtils.d(TAG, "onSdcardStateFormatting");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateNoSpace() {
            LogUtils.d(TAG, "onSdcardStateNoSpace");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateWriteFail() {
            LogUtils.d(TAG, "onSdcardStateWriteFail");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateSdcardIncompatible() {
            LogUtils.d(TAG, "onSdcardStateSdcardIncompatible");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStateEmergencyAreaOverThreshold() {
            LogUtils.d(TAG, "onSdcardStateEmergencyAreaOverThreshold");
            updateTfCardLay();
        }

        @Override
        public void onSdcardStatePrivateFilesTakeTooMuchSpace() {
            LogUtils.d(TAG, "onSdcardStatePrivateFilesTakeTooMuchSpace");
            updateTfCardLay();
        }

        @Override
        public void onSdCardStateEmergencyVideoPartitionFull() {
            LogUtils.d(TAG, "onSdCardStateEmergencyVideoPartitionFull");
            updateTfCardLay();
        }

        @Override
        public void onSdCardStatePhotoPartitionFull() {
            LogUtils.d(TAG, "onSdCardStatePhotoPartitionFull");
            updateTfCardLay();
        }
    };

    private final IDvrAPI.IOperateResultsWatcher mOperateResultsWatcher = new IDvrAPI.IOperateResultsWatcher() {
        @Override
        public void onDvrCaptureInProgress() {
        }

        @Override
        public void onDvrCaptureSuccess() {
        }

        @Override
        public void onDvrCaptureFail() {
        }

        @Override
        public void onDvrGeneralRecordInProgress() {
        }

        @Override
        public void onDvrGeneralRecordSuccess() {
        }

        @Override
        public void onDvrGeneralRecordFail() {
        }

        @Override
        public void onDvrPauseGeneralRecordInProgress() {
        }

        @Override
        public void onDvrPauseGeneralRecordSuccess() {
        }

        @Override
        public void onDvrPauseGeneralRecordFail() {
        }

        @Override
        public void onDvrEmergencyRecordInProgress() {
        }

        @Override
        public void onDvrEmergencyRecordSuccess() {
        }

        @Override
        public void onDvrEmergencyRecordFail() {
        }

        @Override
        public void onFactoryResetInProgress() {
        }

        @Override
        public void onFactoryResetSuccess() {
        }

        @Override
        public void onFactoryResetFail() {
        }

        @Override
        public void onSdcardFormatInProgress() {
            LogUtils.d(TAG, "onSdcardFormatInProgress");
        }

        @Override
        public void onSdcardFormatSuccess() {
            LogUtils.d(TAG, "onSdcardFormatSuccess");
            dismissTfCardFormatLoadingDialog();
            Toast.makeText(AppUtils.getApp(), R.string.tf_card_format_success, Toast.LENGTH_LONG).show();
        }

        @Override
        public void onSdcardFormatFail() {
            LogUtils.d(TAG, "onSdcardFormatFail");
            dismissTfCardFormatLoadingDialog();
        }

        @Override
        public void onOperationUnknown() {
        }
    };

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Fragment fragment = getParentFragment();
        if (fragment instanceof MainFragment) {
            mMainFragment = (MainFragment) fragment;
        }
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_settings;
    }

    @Override
    protected void initData() {
        super.initData();
        DvrManager.get().registerDvrConfigWatcher(mDvrConfigWatcher);
        DvrManager.get().registerSdcardStateWatcher(mSdcardStateWatcher);
        DvrManager.get().registerOperateResultsWatcher(mOperateResultsWatcher);
        AospCarManager.get().isRequiresDistractionOptimization().observe(this, aBoolean -> {
            isRequiresDistractionOptimization = aBoolean;
            mTvTitlePrivacyPolicy.setCompoundDrawablesWithIntrinsicBounds(0, 0,aBoolean? R.drawable.ic_mini_arrow_angle_deep:
                    R.drawable.ic_mini_arrow_angle_light , 0);
            mTvTitlePrivacyPolicy.setTextColor(aBoolean? ContextCompat.getColor(mTvTitlePrivacyPolicy.getContext(),R.color.camera_base_tv_common_text_color_disabled) :
                    ContextCompat.getColor(mTvTitlePrivacyPolicy.getContext(),R.color.camera_base_highlight_color));
        });
    }

    @Override
    public void onDestroy() {
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
            mHandler = null;
        }
        super.onDestroy();
        DvrManager.get().unregisterDvrConfigWatcher(mDvrConfigWatcher);
        DvrManager.get().unregisterSdcardStateWatcher(mSdcardStateWatcher);
        DvrManager.get().unregisterOperateResultsWatcher(mOperateResultsWatcher);
        dismissTfCardFormatDialog();
        dismissTfCardFormatLoadingDialog();
    }

    @SuppressLint("CutPasteId")
    @Override
    protected void bindViews() {
        super.bindViews();
        fgColorTvs = new TextView[] {
                view.findViewById(R.id.rb_loop_record_1min),
                view.findViewById(R.id.rb_loop_record_3min),
                view.findViewById(R.id.rb_loop_record_5min)
        };

        mTfCardBtn = view.findViewById(R.id.btn_tf_card);
        mTfCardProgressBar = view.findViewById(R.id.progress_bar_tf_card);
        mTfCardPercentageTxt = view.findViewById(R.id.percentage_txt_tf_card);
        mTfCardBtn.setOnClickListener(v -> {
            // 格式化弹窗
            showTfCardFormatDialog();
        });

        viewDivideLines = new View[] {view.findViewById(R.id.view_divide_line_privacy_policy)};
        tvTitlePrivacyPolicy = view.findViewById(R.id.lay_item_privacy_policy);
        mTvTitlePrivacyPolicy = view.findViewById(R.id.tv_title_privacy_policy);

        tvTitlePrivacyPolicy.setOnClickListener(v -> {
            if(isRequiresDistractionOptimization){
                Toast.makeText(AppUtils.getApp(), R.string.settings_requires_distraction_optimization_toast, Toast.LENGTH_LONG).show();
                return;
            }
            if (mMainFragment != null) {
                mMainFragment.showPrivacySettingsShade(true);
            }
            DialogUtils.showPrivatePolicyDialog(getFragmentManager(), dialog -> {
                ConfigManager.getInstance().setPrivatePrivacyAgreed(true);
                dialog.dismiss();
            }, mPrivacyDismissListener);
        });

        mLoopRecordRg = view.findViewById(R.id.rg_loop_recording);
//        mLoopRecordRg.setOnCheckedChangeListener((group, checkedId) -> {
//            DvrManager.get().setDvrGeneralRecordDuration(getLoopRecordCycleTime(checkedId));
//        });
        View rb_loop_record_1min = view.findViewById(R.id.rb_loop_record_1min);
        View rb_loop_record_3min = view.findViewById(R.id.rb_loop_record_3min);
        View rb_loop_record_5min = view.findViewById(R.id.rb_loop_record_5min);

        rb_loop_record_1min.setOnClickListener(v -> {
                    LogUtils.d(TAG, "updateLoopRecordRadioGroup DURATION_1_MIN");
                    removeDelayUpdateLoopRecordRadioGroupMsg();
                    DvrManager.get().setDvrGeneralRecordDuration(Constants.LoopRecordDuration.DURATION_1_MIN);
                }
        );
        rb_loop_record_3min.setOnClickListener(v -> {
                    LogUtils.d(TAG, "updateLoopRecordRadioGroup DURATION_3_MIN");
                    removeDelayUpdateLoopRecordRadioGroupMsg();
                    DvrManager.get().setDvrGeneralRecordDuration(Constants.LoopRecordDuration.DURATION_3_MIN);
                }
        );
        rb_loop_record_5min.setOnClickListener(v -> {
                    LogUtils.d(TAG, "updateLoopRecordRadioGroup DURATION_5_MIN");
                    removeDelayUpdateLoopRecordRadioGroupMsg();
                    DvrManager.get().setDvrGeneralRecordDuration(Constants.LoopRecordDuration.DURATION_5_MIN);
                }
        );

    }

    private void updateLoopRecordRadioGroup() {
        LogUtils.d(TAG, "updateLoopRecordRadioGroup");
        int id = getCurLoopRecordRbId();
        if (mLoopRecordRg != null && id != -1) {
            mLoopRecordRg.check(id);
        }
        isNeedDelayUpdateLoopRecordRadioGroup = false;
    }

    private int getCurLoopRecordRbId() {
        int loopRecordCycleTime = DvrManager.get().getDvrGeneralRecordDuration();
        LogUtils.d(TAG, "getCurLoopRecordRbId loopRecordCycleTime=" + loopRecordCycleTime);
        if (Constants.LoopRecordDuration.DURATION_1_MIN == loopRecordCycleTime) {
            return R.id.rb_loop_record_1min;
        }
        if (Constants.LoopRecordDuration.DURATION_5_MIN == loopRecordCycleTime) {
            return R.id.rb_loop_record_5min;
        }
        if (Constants.LoopRecordDuration.DURATION_3_MIN == loopRecordCycleTime) {
            return R.id.rb_loop_record_3min;
        }
        return -1;
    }

    private int getLoopRecordCycleTime(int checkedId) {
        if (R.id.rb_loop_record_1min == checkedId) {
            return Constants.LoopRecordDuration.DURATION_1_MIN;
        }
        if (R.id.rb_loop_record_5min == checkedId) {
            return Constants.LoopRecordDuration.DURATION_5_MIN;
        }
        return Constants.LoopRecordDuration.DURATION_3_MIN;
    }

    /**
     * 更新TfCard相关布局
     */
    private void updateTfCardLay() {
        boolean isTfCardExist = DvrManager.get().isDvrSdcardExists();
        int percentage = DvrManager.get().getSdcardUsedPercentage();
        LogUtils.d(TAG, "updateTfCardLay, isTfCardExist:" + isTfCardExist + ", percentage:" + percentage);
        if (isTfCardExist) {
            mTfCardBtn.setText(R.string.camera_settings_tf_card_format);
            mTfCardBtn.setEnabled(true);

            if (percentage >= MIN_PERCENTAGE && percentage <= MAX_PERCENTAGE) {
                mTfCardProgressBar.setProgress(percentage);
                mTfCardPercentageTxt.setText(getResources().getString(R.string.camera_settings_tf_card_percentage_format, percentage));
            } else {
                mTfCardProgressBar.setProgress(0);
                mTfCardPercentageTxt.setText(R.string.tf_card_percentage_unknown);
            }
            mTfCardProgressBar.setVisibility(View.VISIBLE);
            mTfCardPercentageTxt.setVisibility(View.VISIBLE);
        } else {
            mTfCardBtn.setText(R.string.camera_settings_tf_card_not_found);
            mTfCardBtn.setEnabled(false);

            mTfCardProgressBar.setVisibility(View.GONE);
            mTfCardPercentageTxt.setVisibility(View.GONE);
        }
    }

    /**
     * 显示TfCard格式化对话框
     */
    private void showTfCardFormatDialog() {
        if (mTfCardFormatDialog != null && mTfCardFormatDialog.isShowing()) {
            LogUtils.d(TAG, "showTfCardFormatDialog, dialog is already showing");
            return;
        }
        LogUtils.d(TAG, "showTfCardFormatDialog");
        mTfCardFormatDialog = DialogUtils.showTfCardFormatDialog(getContext(), mFormatCancelClickListener, mFormatConfirmClickListener);
    }

    /**
     * 隐藏TfCard格式化对话框
     */
    private void dismissTfCardFormatDialog() {
        LogUtils.d(TAG, "dismissTfCardFormatDialog");
        if (mTfCardFormatDialog != null && mTfCardFormatDialog.isShowing()) {
            mTfCardFormatDialog.dismiss();
        }
    }

    /**
     * 显示TfCard格式化加载中对话框
     */
    private void showTfCardFormatLoadingDialog() {
        if (mTfCardFormatLoadingDialog != null && mTfCardFormatLoadingDialog.isShowing()) {
            LogUtils.d(TAG, "showTfCardFormatLoadingDialog, dialog is already showing");
            return;
        }
        LogUtils.d(TAG, "showTfCardFormatLoadingDialog");
        mTfCardFormatLoadingDialog = DialogUtils.showLoadingAlertDialog(getContext(), R.string.dialog_formatting, false);
        mTfCardBtn.removeCallbacks(mDismissForFormatTimeoutRunnable);
        mTfCardBtn.postDelayed(mDismissForFormatTimeoutRunnable, FORMATTING_MAX_MILLIS);
    }

    /**
     * 隐藏TfCard格式化加载中对话框
     */
    private void dismissTfCardFormatLoadingDialog() {
        LogUtils.d(TAG, "dismissTfCardFormatDialog");
        if (mTfCardBtn != null) {
            mTfCardBtn.removeCallbacks(mDismissForFormatTimeoutRunnable);
        }
        if (mTfCardFormatLoadingDialog != null && mTfCardFormatLoadingDialog.isShowing()) {
            mTfCardFormatLoadingDialog.dismiss();
        }
    }

    @Override
    protected void initViews() {
        super.initViews();
        for (TextView tvTitle : fgColorTvs) {
            tvTitle.setTextColor(ContextCompat.getColor(Utils.getApp(), R.color.camera_base_day_night_fg_color));
        }
        for (View viewDivideLine : viewDivideLines) {
            viewDivideLine.setBackgroundColor(ContextCompat.getColor(Utils.getApp(), R.color.camera_base_view_divide_line_bg_color));
        }
    }

    @Override
    protected void onResume(boolean firstResume) {
        super.onResume(firstResume);
        LogUtils.d(TAG, "onResume");
        updateTfCardLay();
        updateLoopRecordRadioGroup();
    }

    private void removeDelayUpdateLoopRecordRadioGroupMsg() {
        if (mHandler == null) {
            return;
        }
        isNeedDelayUpdateLoopRecordRadioGroup = true;
        mHandler.removeMessages(HANDLER_DELAY_UPDATE_RECORD_RADIO_GROUP);
    }

    /**
     * 延迟一秒钟更新循环录制RadioGroup
     */
    private void sendDelayUpdateLoopRecordRadioGroupMsg() {
        if (mHandler == null) {
            return;
        }
        mHandler.removeMessages(HANDLER_DELAY_UPDATE_RECORD_RADIO_GROUP);
        mHandler.sendEmptyMessageDelayed(HANDLER_DELAY_UPDATE_RECORD_RADIO_GROUP, 1000);
    }
}
